package info.nixbear.tgcms.admin.client.activity;

import info.nixbear.tgcms.admin.client.place.TemplatesPlace;
import info.nixbear.tgcms.admin.client.place.TemplatesPlace.TemplateEditPlace;
import info.nixbear.tgcms.admin.client.view.TemplateEditView;
import info.nixbear.tgcms.admin.client.view.TemplateEditor;
import info.nixbear.tgcms.admin.shared.request.AdminRequestFactory;
import info.nixbear.tgcms.admin.shared.request.TemplateProxy;
import info.nixbear.tgcms.admin.shared.request.TemplateRequest;

import java.util.List;
import java.util.Set;

import com.google.gwt.activity.shared.AbstractActivity;
import com.google.gwt.activity.shared.Activity;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.inject.Inject;
import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryEditorDriver;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.RequestContext;
import com.google.web.bindery.requestfactory.shared.Violation;

public class TemplateEditActivity extends AbstractActivity {

	private TemplateEditView view;
	private PlaceController placeController;
	private AdminRequestFactory requestFactory;
	private TemplateEditPlace place;
	private Driver editorDriver;

	interface Driver extends RequestFactoryEditorDriver<TemplateProxy, TemplateEditor> { }

	@Inject
	public TemplateEditActivity(
			TemplateEditView view, 
			PlaceController placeController,
			AdminRequestFactory requestFactory) 
	{
		this.view = view;
		this.placeController = placeController;
		this.requestFactory = requestFactory;
	}

	public Activity withPlace(TemplateEditPlace place) {
		this.place = place;
		return this;
	}

	
	@Override
	public void start(final AcceptsOneWidget panel, EventBus eventBus) {
		view.setTemplateEditActivity(this);
		
		
		this.requestFactory.templateRequest().listAll()
			.fire(new Receiver<List<TemplateProxy>>(){

			@Override
			public void onSuccess(List<TemplateProxy> response) {
				view.getEditor().setTemplates(response);
				
				edit(panel);
			}});
		
		
		
	}

	private void edit(final AcceptsOneWidget panel) {
		
		
		editorDriver = GWT.create(Driver.class);
		editorDriver.initialize(requestFactory, view.getEditor());
		
		if(place.isTokenANewToken()) {
			TemplateRequest request = requestFactory.templateRequest();
			TemplateProxy tempalte = request.create(TemplateProxy.class);
					
			edit(panel, tempalte, request);
		} else {
			
			final TemplateProxy template = place.getTemplate();
		
			
			Request<TemplateProxy> fetchRequest = 
				(template == null)
					?requestFactory.templateRequest().get(Long.valueOf(place.getToken()))
						:requestFactory.find(template.stableId());
		
			fetchRequest.with(editorDriver.getPaths());
			fetchRequest.to(new Receiver<TemplateProxy>() {
				@Override
				public void onSuccess(TemplateProxy page) {
					TemplateRequest request = requestFactory.templateRequest();
					edit(panel, template, request);
				}
			}).fire();
		}

		
	}
	
	public void edit(AcceptsOneWidget panel, TemplateProxy template, TemplateRequest request) {
		editorDriver.edit(template, request);
		request.put(template);
		
		panel.setWidget(view.asWidget());
	}
	
	
	
	public void goTo(Place place) {
		placeController.goTo(place);
	}


	public void onSave(ClickEvent event) {
		// Flush the contents of the UI
		RequestContext context = editorDriver.flush();

		// Check for errors
		if (editorDriver.hasErrors()) {
			Window.alert("Errors detected locally");
			return;
		}

		// Send the request
		context.fire(new Receiver<Void>() {
			public void onViolation(Set<Violation> errors) {
				// Otherwise, show ConstraintViolations in the UI
				Window.alert("Errors detected on the server");
				editorDriver.setViolations(errors);
			}

			@Override
			public void onSuccess(Void response) {
				placeController.goTo(new TemplatesPlace());
			}
		});
	}
	
	public void onCancel(ClickEvent event) {
		placeController.goTo(new TemplatesPlace());
	}

	@Override
	public void onStop() {
		view.setTemplateEditActivity(null);
	}

	

}
